#pragma once
#include "Socket.hpp"
#include "Log.hpp"
static const int defaultport = 8082;
class ThreadData
{
public:
    ThreadData(int fd) : sockfd(fd) //,svr(s)
    {
    }

public:
    int sockfd;
    // HttpServer *svr;
};
// class HandlerHttp ;
class HttpServer
{
public:
    HttpServer(uint16_t port = defaultport) : port_(port)
    {
    }
    ~HttpServer()
    {
    }

public:
    static void HandlerHttp(int sockfd)
    {
        char buffer[10240];
        // 接受请求
        int n = recv(sockfd, buffer, sizeof(buffer) - 1, 0); // 与read函数类似
        if (n > 0)
        {
            buffer[n] = 0;                    // 将buffer当成字符串处理
            std::cout << buffer << std::endl; // 假设我们读取到的就是一个完整的，独立的http 请求
        }

        // 构建响应
        std::string text = "hello world";
        std::string response_line = "HTTP/1.0 200 OK\r\n";
        std::string response_header = "Content-Length:";
        response_header += std::to_string(text.size()); // Content-Length:11
        response_header += "\r\n";
        std::string blank_line = "\r\n"; // 空行，表示头部和正文的分隔
        std::string response = response_line;
        response += response_header;
        response += blank_line;
        response += text;

        send(sockfd, response.c_str(), response.size(), 0);//send函数类似于write
        // 返回响应

        close(sockfd);
    }
    // 不加static ,ThreadRun函数是类的成员函数 ，void *ThreadRun(HttpServer * this ,void *args)
    // 与pthread_create的参数  ，void *(*start_routine) (void *) ,参数个数不一致
    // 加了static，ThreadRun就不是类的成员函数
    static void *ThreadRun(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *td = (ThreadData *)args;
        HandlerHttp(td->sockfd);
        close(td->sockfd);
        delete td;
        return nullptr;
    }
    bool Start()
    {
        // 创建套接字
        listensock_.Socket();
        // 绑定端口
        listensock_.Bind(port_);
        // 监听
        listensock_.Lisenten();
        // 服务
        for (;;)
        {
            // 服务器需要获取到客户端的连接请求
            std::string clientip;
            uint16_t clientport;
            int sockfd = listensock_.Accept(&clientip, &clientport);
            if (sockfd < 0)
                continue;
            lg(Info, " HttpServer.cc:get a new connect, sockfd: %d", sockfd);
            // 线程
            pthread_t tid;
            ThreadData *td = new ThreadData(sockfd);
            pthread_create(&tid, nullptr, ThreadRun, td);
        }
    }

private:
    Sock listensock_; // 监听套接字
    uint16_t port_;
};